package com.clss.webrtclibrary;

import android.support.annotation.NonNull;

import java.util.HashMap;
import java.util.concurrent.DelayQueue;
import java.util.concurrent.Delayed;
import java.util.concurrent.TimeUnit;

/** 作为一只看门狗，监视视频信令的回复是不是在规定时间内拿到了，没能拿到就叫 */
public class SignalingAnswerWatcherDog {

    private String TAG = this.getClass().getSimpleName();

    private DelayQueue<SignalingAnswerTask> mQueue = new DelayQueue<>();
    private SignalingAnswerOutTimeListener mListener;
    private HashMap<String, SignalingAnswerTask> mTempMap = new HashMap<>();
    private Thread mQueueThread;
    private boolean isLoop = true;

    private Runnable mQueueRun = new Runnable() {
        @Override
        public void run() {
            while (isLoop){
                try {
                    SignalingAnswerTask dog = mQueue.take();
                    if (mListener != null){
                        Lg.i(TAG, "---onSignalingAnswerOutTime===" + dog.getType());
                        mListener.onSignalingAnswerOutTime(dog.getType());
                    }
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    };

    public SignalingAnswerWatcherDog(SignalingAnswerOutTimeListener mListener) {
        this.mListener = mListener;
    }

    /** 把狗叫醒，接收任务 */
    public void wakeUpDog(String type){
        SignalingAnswerTask dogType = null;
        if (type.equals(KurentoSignActionType.joinRoom.name())){
            dogType = new SignalingAnswerTask(KurentoSignActionType.joinRoomAnswer.name());
            mTempMap.put(KurentoSignActionType.joinRoomAnswer.name(), dogType);
        }else if (type.equals(KurentoSignActionType.publish.name())){
            dogType = new SignalingAnswerTask(KurentoSignActionType.publishAnswer.name());
            mTempMap.put(KurentoSignActionType.publishAnswer.name(), dogType);
        }else if (type.equals(KurentoSignActionType.create.name())){
            dogType = new SignalingAnswerTask(KurentoSignActionType.createResponse.name());
            mTempMap.put(KurentoSignActionType.createResponse.name(), dogType);
        }else if (type.equals(KurentoSignActionType.start.name())){
            dogType = new SignalingAnswerTask(KurentoSignActionType.startResponse.name());
            mTempMap.put(KurentoSignActionType.startResponse.name(), dogType);
        }else if (type.equals(KurentoSignActionType.receiveVideoFrom.name())){
            dogType = new SignalingAnswerTask(KurentoSignActionType.receiveVideoAnswer.name());
            mTempMap.put(KurentoSignActionType.receiveVideoAnswer.name(), dogType);
        }
        if (dogType != null){
            mQueue.put(dogType);
        }else {
            return;
        }
        isLoop = true;
        if (mQueueThread == null){
            mQueueThread = new Thread(mQueueRun);
            mQueueThread.start();
        }
    }

    /** 喂狗 */
    public void feedDog(String type){
        if (mTempMap.containsKey(type)){
            mQueue.remove(mTempMap.get(type));
            mTempMap.remove(type);
        }
    }

    /** 狗归位 */
    public void clearDog(){
        isLoop = false;
    }

    private static class SignalingAnswerTask implements Delayed{
        private long DELAY_LENGTH = 30 * 1000;
        private String type;
        private long time;

        public SignalingAnswerTask(String type, long time) {
            this.type = type;
            this.time = System.currentTimeMillis() + time;
        }

        public SignalingAnswerTask(String type) {
            this.type = type;
            this.time = System.currentTimeMillis() + DELAY_LENGTH;
        }

        public String getType() {
            return type;
        }

        @Override
        public long getDelay(@NonNull TimeUnit unit) {
            return unit.convert(time - System.currentTimeMillis(), TimeUnit.MILLISECONDS);
        }

        @Override
        public int compareTo(@NonNull Delayed o) {
            return  this.getDelay(TimeUnit.MILLISECONDS) - o.getDelay(TimeUnit.MILLISECONDS) > 0 ? 1:0;
        }
    }

    public interface SignalingAnswerOutTimeListener{
        /** 狗叫 */
        void onSignalingAnswerOutTime(String type);
    }
}
